//file:src/system/vm/dma.h
//autor：jiangxinpeng
//time: 2021.11.28
//copyright: (C) 2020-2050 by jiangxinpeng,All right are reserved.

#include <os/dma.h>
#include <os/mutexlock.h>
#include <os/memcache.h>
#include <os/vmm.h>
#include <os/debug.h>
#include <os/virmem.h>
#include <arch/page.h>
#include <lib/stddef.h>
#include <lib/type.h>

int DmaAllocBuffer(dma_region_t *dma)
{
    int pages = DIV_ROUND_UP(dma->p.size, PAGE_SIZE);
    address_t vaddr;

    if (!dma->p.size)
        return -1;
    if (dma->flags & DMA_REGION_SPECIAL)
    {
        //alloc in dma area
        dma->p.addr = ADDR(AllocDmaPage(pages));
        if (!dma->p.addr)
        {
            KPrint("[dma] dma alloc failed!\n");
            return -1;
        }
    }
    else
    {
        //kernel
        dma->p.addr = ADDR(AllocKernelPage(pages));
        if (!dma->p.addr)
        {
            return -1;
        }
    }
    vaddr = ADDR(KERNEL_PYBASE2VBASE(dma->p.addr));
    dma->v = vaddr;
    return 0;
}

int DmaFreeBuffer(dma_region_t *dma)
{
    if (!dma->p.size || !dma->p.addr || !dma->v)
        return -1;
    FreePage(dma->p.addr);
    dma->p.addr = dma->v = 0;
    return 0;
}

void DmaBufferDump(dma_region_t *dma)
{
    KPrint("dma region vaddr:%x paddr:%x size:%d flags:%x\n", dma->v, dma->p.addr, dma->p.size, dma->flags);
}